package cz.cvut.manatee.client.concordance;

import java.util.ArrayList;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;

import cz.cvut.manatee.client.Resources;
import cz.cvut.manatee.shared.concordance.ResultTableRow;
import cz.cvut.manatee.shared.concordance.ResultTableWord;

public class ResultsTableWigdet extends Composite{

	private final String KEYWORD_ATTRIBUTS 			= "Atributy";
	private final String KEYWORD_LEFT_CONTEXT 		= "Levý kontext";
	private final String KEYWORD_KWIC 				= "Kwic";
	private final String KEYWORD_RIGHT_CONTEXT 		= "Pravý kontext";
	private final String KEYWORD_ADD_NEXT_RESULTS 	= "Připojit další stranu";
	private final String KEYWORD_SHOW_NEXT_RESULTS 	= "Zobrazit další stranu";
	
	private final FlexTable resultTable;
	private final Button addResultsButton;
	private final Button nextResultsButton;
	private final VerticalPanel resultPanel;
	private final HorizontalPanel buttonPanel;
	
	private final ArrayList<Integer> selectedRows;

	private int maxLeftContext;
	private int maxRightContext;
	private int kwicCount;
	private int attrCount;

	private boolean showContextWord  = true;
	private boolean showContextLemma = false;
	private boolean showContextTag   = false;
	private boolean showContextLc    = false;
	private boolean showContextK     = false;
	private boolean showContextG     = false;
	private boolean showContextC     = false;

	private boolean showKwicWord  = true;
	private boolean showKwicLemma = false;
	private boolean showKwicTag   = false;
	private boolean showKwicLc    = false;
	private boolean showKwicK     = false;
	private boolean showKwicG     = false;
	private boolean showKwicC     = false;

	private ResultsTableSource source;

	public ResultsTableWigdet(){
		resultTable  = new FlexTable();
		selectedRows = new ArrayList<Integer>();

		addResultsButton = new Button(KEYWORD_ADD_NEXT_RESULTS);	
		nextResultsButton = new Button(KEYWORD_SHOW_NEXT_RESULTS);
		resultPanel = new VerticalPanel();
		
		buttonPanel = new HorizontalPanel();
		buttonPanel.add(addResultsButton);
		buttonPanel.add(nextResultsButton);

		initWidget(resultPanel);
		
		Resources.INSTANCE.resultTable().ensureInjected();;
		resultTable.setStylePrimaryName(Resources.INSTANCE.resultTable().resultTable());

		
		/*
		 * toto se pouzije pri oznacovani radku pomoci kliknuti
		 * 
		resultTable.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent e){
				int rowIndex = ResultsTableWigdet.this.resultTable.getCellForEvent(e).getRowIndex();
				if(rowIndex==0) return; //nekdo klidknul na header
				
				int arrayIndex = ResultsTableWigdet.this.selectedRows.indexOf(rowIndex);
				if(arrayIndex<0){
					ResultsTableWigdet.this.selectedRows.add(rowIndex);
					ResultsTableWigdet.this.resultTable.getRowFormatter().addStyleName(rowIndex, "selected");
				}
				else{
					ResultsTableWigdet.this.selectedRows.remove(arrayIndex);
					ResultsTableWigdet.this.resultTable.getRowFormatter().removeStyleName(rowIndex, "selected");
				}
			}
		});
		*/
	}
	
	public ResultsTableWigdet(ResultsTableSource source){
		this();
		this.source = source;
	}
	
	public void addSource(ResultsTableSource source) {
		if(source != null){
			int startIndex = this.source.getRowsCount();
			
			this.source.addSourceData(source);
			
			addTailTableData(startIndex);
		}
	}

	public Button getAddResultsButton(){
		return addResultsButton;
	}

	public void disableAddResultsButton(){
		addResultsButton.setEnabled(false);
	}

	public void enableAddResultsButton(){
		addResultsButton.setEnabled(true);
	}

	public Button getNextResultsButton(){
		return nextResultsButton;
	}

	public void disableNextResultsButton(){
		nextResultsButton.setEnabled(false);
	}

	public void enableNextResultsButton(){
		nextResultsButton.setEnabled(true);
	}

	public void setShowedAtributsInContext(boolean showContextWord, boolean showContextLemma, boolean showContextTag, boolean showContextLc, boolean showContextK, boolean showContextG, boolean showContextC){
		this.showContextWord = showContextWord;
		this.showContextLemma = showContextLemma;
		this.showContextTag = showContextTag;
		this.showContextLc = showContextLc;
		this.showContextK = showContextK;
		this.showContextG = showContextG;
		this.showContextC = showContextC;
	}

	public void setShowedAtributsInKwic(boolean showKwicWord, boolean showKwicLemma, boolean showKwicTag, boolean showKwicLc, boolean showKwicK, boolean showKwicG, boolean showKwicC){
		this.showKwicWord = showKwicWord;
		this.showKwicLemma = showKwicLemma;
		this.showKwicTag = showKwicTag;
		this.showKwicLc = showKwicLc;
		this.showKwicK = showKwicK;
		this.showKwicG = showKwicG;
		this.showKwicC = showKwicC;
	}

	public void rebuildTable(ResultsTableSource source){
		this.source = source;
		buildTable();
	}

	public ArrayList<Integer> getSelectedRows(){
		return selectedRows;
	}

	public void buildTable(){
		//TODO nemam v GWT tuto metodu prozatim tedy pouziji vlastni
		//resultTable.removeAllRows();
		removeAllRows();
		
		fillTable();
	}

	private void fillTable(){
		
		maxLeftContext = source.getMaxLeftContext();
		maxRightContext = source.getMaxRightContext();
		kwicCount = source.getKwicCount();
		attrCount = source.getAttrCount();

		addHeader(attrCount,maxLeftContext, kwicCount, maxRightContext);
		addBody(0, attrCount,maxLeftContext, kwicCount, maxRightContext);

		resultPanel.clear();
		resultPanel.add(resultTable);
		resultPanel.add(buttonPanel);
		enableAddResultsButton();
		enableNextResultsButton();
	}

	public void addTailTableData(int StartIndex){
		addBody(StartIndex, attrCount,maxLeftContext, kwicCount, maxRightContext);
	}

	private void addHeader(int atributsCount, int maxLeftContext, int kwicCount, int maxRightContext){
		
		resultTable.setText(0, 0, KEYWORD_ATTRIBUTS);
		resultTable.setText(0, 1, KEYWORD_LEFT_CONTEXT);
		resultTable.setText(0, 2, KEYWORD_KWIC);
		resultTable.setText(0, 3, KEYWORD_RIGHT_CONTEXT);
			
		FlexCellFormatter formater = resultTable.getFlexCellFormatter();

		formater.setColSpan(0, 0, atributsCount);
		formater.setColSpan(0, 1, maxLeftContext);
		formater.setColSpan(0, 2, kwicCount);
		formater.setColSpan(0, 3, maxRightContext);
		

	}

	private void addBody(int startIndex, int atributsCount, int maxLeftContext, int kwicCount, int maxRightContext){
		ArrayList<ResultTableRow> data = source.getData();

		int line, row, word = 0;
		
		for(line=startIndex; line<data.size(); line++){
			//sloupce je treba projet rucne
			row = 0;
			
			for(word=0; word<Math.min(data.get(line).getAttributs().length, atributsCount); word++){
				resultTable.setText(line+1, row++, data.get(line).getAttributs()[word]);
			}
			//doplneni prazdnych mist v attrs
			for(word=0; word<(atributsCount-data.get(line).getAttributs().length); word++){
				resultTable.setText(line+1, row++, "");
			}

			//doplneni prazdnych mist v left context
			for(word=0; word<(maxLeftContext-data.get(line).getLeftContexts().length); word++){
				resultTable.setText(line+1, row++, "");
			}
			for(word=0; word<Math.min(data.get(line).getLeftContexts().length, maxLeftContext); word++){
				resultTable.setText(line+1, row++, getAttributes(data.get(line).getLeftContexts()[word], showContextWord, showContextLemma, showContextTag, showContextLc, showContextK, showContextG, showContextC));
			}
			
			for(word=0; word<Math.min(data.get(line).getKwics().length, kwicCount); word++){
				resultTable.setText(line+1, row++, getAttributes(data.get(line).getKwics()[word], showKwicWord, showKwicLemma, showKwicTag, showKwicLc, showKwicK, showKwicG, showKwicC));
			}
			//doplneni prazdnych mist v kwic kdyby nahodou
			for(word=0; word<(kwicCount-data.get(line).getKwics().length); word++){
				resultTable.setText(line+1, row++, "");
			}
			
			for(word=0; word<Math.min(data.get(line).getRightContexts().length, maxRightContext); word++){
				resultTable.setText(line+1, row++, getAttributes(data.get(line).getRightContexts()[word], showContextWord, showContextLemma, showContextTag, showContextLc, showContextK, showContextG, showContextC));
			}
			//doplneni prazdnych mist v right context
			for(word=0; word<(maxRightContext-data.get(line).getRightContexts().length); word++){
				resultTable.setText(line+1, row++, "");
			}
		}
		
		formatTable();
		
	}
	
	  /**
	   * Remove all rows in this table.
	   */
	  private void removeAllRows() {
	     int numRows = resultTable.getRowCount();
	     for (int i = 0; i < numRows; i++) {
	    	 resultTable.removeRow(0);
	     }
	  }

	  private void formatTable(){
		  formatHeaders();
		  formatDataColls(0,attrCount, Resources.INSTANCE.resultTable().attr());
		  formatDataColls(attrCount, attrCount+maxLeftContext, "leftContext");
		  formatDataColls(attrCount+maxLeftContext, attrCount+maxLeftContext+kwicCount, Resources.INSTANCE.resultTable().kwic());
		  formatDataColls(attrCount+maxLeftContext+kwicCount, attrCount+maxLeftContext+kwicCount+maxRightContext, "rightContext");
	  }

	  private void formatHeaders(){
		  FlexCellFormatter formatter = resultTable.getFlexCellFormatter();
		  
		  for(int i=0; i<resultTable.getCellCount(0); i++){
			  formatter.addStyleName(0, i, Resources.INSTANCE.resultTable().header());
		  }
	  }

	  private void formatDataColls(int from, int to, String styleName){
		  FlexCellFormatter formatter = resultTable.getFlexCellFormatter();
		  
		  for(int i=1; i<resultTable.getRowCount(); i++){
			  for(int j=from; j<to; j++){
				  formatter.addStyleName(i, j, styleName);
			  }
		  }
	  }

	 private String getAttributes(ResultTableWord tableWord, boolean word, boolean lemma, boolean tag, boolean lc, boolean k, boolean g, boolean c){
		 String text = ((word)?tableWord.getWord()+"/":"") + ((lemma)?tableWord.getLemma()+"/":"") + ((tag)?tableWord.getTag()+"/":"") + ((lc)?tableWord.getLc()+"/":"") + ((k)?tableWord.getK()+"/":"") + ((g)?tableWord.getG()+"/":"") + ((c)?tableWord.getC()+"/":"");
		 if(text.endsWith("/")) text = text.replaceAll("/$", "");
		 return text;
	 }
}
